#include "FontSettings.h"

#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QSettings>
#include <QtCore/QCoreApplication>
#include <QtGui/QTextCharFormat>
#include <QDebug>

static const char * const groupKey = "EditorFontSettings";
static const char * const keyFontFamily = "FontFamily";
static const char * const keyFontSize = "FontSize";
static const char * const keyAntialias = "FontAntialias";

namespace {
static const bool DEFAULT_ANTIALIAS = true;
#ifdef Q_WS_MAC
    enum { DEFAULT_FONT_SIZE = 12 };
    static const char *DEFAULT_FONT_FAMILY = "Monaco";
#else
#ifdef Q_WS_X11
    enum { DEFAULT_FONT_SIZE = 9 };
    static const char *DEFAULT_FONT_FAMILY = "Monospace";
#else
    enum { DEFAULT_FONT_SIZE = 10 };
    static const char *DEFAULT_FONT_FAMILY = "Courier New";
#endif
#endif
} // anonymous namespace

namespace CodeEdit {

//! @class FontSettings
FontSettings::FontSettings()
    : _family(defaultFixedFontFamily())
    , _fontSize(DEFAULT_FONT_SIZE)
    , _antialias(DEFAULT_ANTIALIAS)
{
}

void FontSettings::clear()
{
    _family = defaultFixedFontFamily();
    _fontSize = DEFAULT_FONT_SIZE;
    _antialias = DEFAULT_ANTIALIAS;
}

void FontSettings::toSettings(QSettings *s) const
{
    s->beginGroup(QLatin1String(groupKey));
    s->setValue(QLatin1String(keyFontFamily), _family);
    s->setValue(QLatin1String(keyFontSize), _fontSize);
    s->setValue(QLatin1String(keyAntialias), _antialias);
    s->endGroup();
}

void FontSettings::fromSettings(QSettings *s)
{
    s->beginGroup(QLatin1String(groupKey));
    _family = s->value(QLatin1String(keyFontFamily), defaultFixedFontFamily()).toString();
    _fontSize = s->value(QLatin1String(keyFontSize), _fontSize).toInt();
    _antialias = s->value(QLatin1String(keyAntialias), DEFAULT_ANTIALIAS).toBool();
    s->endGroup();
}

bool FontSettings::equals(const FontSettings &f) const
{
    return _family == f._family
        && _fontSize == f._fontSize
        && _antialias == f._antialias;
}

/**
 * Returns the QTextCharFormat of the given format category.
 */
QTextCharFormat FontSettings::toTextCharFormat(const QString &category) const
{
    QTextCharFormat tf;
    tf.setFontFamily(_family);
    tf.setFontStyleStrategy(_antialias ? QFont::PreferAntialias : QFont::NoAntialias);
    return tf;
}

/**
 * Returns the list of QTextCharFormats that corresponds to the list of
 * requested format categories.
 */
QVector<QTextCharFormat> FontSettings::toTextCharFormats(const QVector<QString> &categories) const
{
    QVector<QTextCharFormat> rc;
    const int size = categories.size();
    rc.reserve(size);
    for (int i = 0; i < size; i++)
         rc.append(toTextCharFormat(categories.at(i)));
    return rc;
}

/**
 * Returns the configured font family.
 */
QString FontSettings::fontFamily() const
{
    return _family;
}

void FontSettings::setFontFamily(const QString &family)
{
    _family = family;
}

/**
 * Returns the configured font size.
 */
int FontSettings::fontSize() const
{
    return _fontSize;
}

void FontSettings::setFontSize(int size)
{
    _fontSize = size;
}

/**
 * Returns the configured antialiasing behavior.
 */
bool FontSettings::antialias() const
{
    return _antialias;
}

void FontSettings::setAntialias(bool antialias)
{
    _antialias = antialias;
}

QString FontSettings::defaultFixedFontFamily()
{
    static QString rc;
    if (rc.isEmpty()) {
        QFont f(DEFAULT_FONT_FAMILY);
        f.setStyleHint(QFont::TypeWriter);
        rc = f.family();
    }
    return rc;
}

int FontSettings::defaultFontSize()
{
    return DEFAULT_FONT_SIZE;
}

} // namespace CodeEdit
